home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / FastMacroWindow.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  29KB  |  1,293 lines

  1. /*
  2. **    FastMacroWindow.c
  3. **
  4. **    Fast! macro window support routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* The scroller gadget IDs. */
  17.  
  18. enum { ARROW_UP=1,ARROW_DOWN };
  19.  
  20.     /* The scroller data. */
  21.  
  22. struct ScrollerInfo
  23. {
  24.     Object *UpImage,*DownImage;
  25.     Object *Scroller,*UpArrow,*DownArrow;
  26.     LONG MinWidth,MinHeight;
  27. };
  28.  
  29.     /* The button margins. */
  30.  
  31. #define MARGIN_X    2
  32. #define MARGIN_Y    2
  33.  
  34. #define GG_Dummy            (TAG_USER+0x4000)
  35. #define GG_List                (GG_Dummy+1)
  36. #define GG_Top                (GG_Dummy+2)
  37. #define GG_Visible            (GG_Dummy+3)
  38. #define GG_Total            (GG_Dummy+4)
  39. #define GG_TopRow            (GG_Dummy+5)
  40. #define GG_ScrollArrow        (GG_Dummy+6)
  41. #define GG_Reset            (GG_Dummy+7)
  42. #define GG_ItemWidth        (GG_Dummy+8)
  43. #define GG_ItemHeight        (GG_Dummy+9)
  44. #define GG_ResetNoRefresh    (GG_Dummy+10)
  45.  
  46. struct GridData
  47. {
  48.     struct List *    List;                    /* The button list. */
  49.     LONG            ListSize;                /* Size of the list. */
  50.  
  51.     LONG            ItemWidth;                /* The width of each button. */
  52.     LONG            ItemHeight;                /* The height of each button. */
  53.  
  54.     LONG            MaxColumns;                /* Maximum number of buttons that can be displayed in a row. */
  55.     LONG            MaxLines;                /* Maximum number of buttons that can be displayed in a column. */
  56.  
  57.     LONG            LastSelected;            /* The button currently selected. */
  58.     LONG            UnselectThis;            /* The button to unselect. */
  59.  
  60.     LONG            LastWidth,LastHeight;    /* Last size of the gadget domain. */
  61.  
  62.     LONG            Top,Visible,Total;        /* Data for the scroller. */
  63.  
  64.     LONG            From,To,Direction;        /* Data for scrolling and display updates. */
  65. };
  66.  
  67.     /* The private data. */
  68.  
  69. STATIC Class                 *GridClass;
  70. STATIC Object                *GridObject;
  71. STATIC struct ScrollerInfo    *GridScroller;
  72.  
  73. STATIC VOID
  74. DeleteScroller(struct ScrollerInfo *ScrollerInfo)
  75. {
  76.     DisposeObject(ScrollerInfo->DownArrow);
  77.     DisposeObject(ScrollerInfo->UpArrow);
  78.     DisposeObject(ScrollerInfo->Scroller);
  79.     DisposeObject(ScrollerInfo->DownImage);
  80.     DisposeObject(ScrollerInfo->UpImage);
  81.  
  82.     FreeVecPooled(ScrollerInfo);
  83. }
  84.  
  85. STATIC struct ScrollerInfo *
  86. CreateScroller(struct Screen *Screen)
  87. {
  88.     struct ScrollerInfo *ScrollerInfo;
  89.  
  90.     if(ScrollerInfo = (struct ScrollerInfo *)AllocVecPooled(sizeof(struct ScrollerInfo),MEMF_ANY|MEMF_CLEAR))
  91.     {
  92.         struct DrawInfo *DrawInfo;
  93.  
  94.         if(DrawInfo = GetScreenDrawInfo(Screen))
  95.         {
  96.             Object *SizeImage;
  97.             LONG SizeType;
  98.  
  99.             if(Screen->Flags & SCREENHIRES)
  100.                 SizeType = SYSISIZE_MEDRES;
  101.             else
  102.                 SizeType = SYSISIZE_LOWRES;
  103.  
  104.             if(SizeImage = NewObject(NULL,SYSICLASS,
  105.                 SYSIA_Size,        SizeType,
  106.                 SYSIA_Which,    SIZEIMAGE,
  107.                 SYSIA_DrawInfo,    DrawInfo,
  108.             TAG_DONE))
  109.             {
  110.                 ULONG SizeWidth,SizeHeight;
  111.  
  112.                 GetAttr(IA_Width,    SizeImage,&SizeWidth);
  113.                 GetAttr(IA_Height,    SizeImage,&SizeHeight);
  114.  
  115.                 DisposeObject(SizeImage);
  116.  
  117.                 if(ScrollerInfo->UpImage = NewObject(NULL,SYSICLASS,
  118.                     SYSIA_Size,        SizeType,
  119.                     SYSIA_Which,    UPIMAGE,
  120.                     SYSIA_DrawInfo,    DrawInfo,
  121.                 TAG_DONE))
  122.                 {
  123.                     ULONG ArrowHeight;
  124.  
  125.                     GetAttr(IA_Height,ScrollerInfo->UpImage,&ArrowHeight);
  126.  
  127.                     if(ScrollerInfo->DownImage = NewObject(NULL,SYSICLASS,
  128.                         SYSIA_Size,        SizeType,
  129.                         SYSIA_Which,    DOWNIMAGE,
  130.                         SYSIA_DrawInfo,    DrawInfo,
  131.                     TAG_DONE))
  132.                     {
  133.                         if(ScrollerInfo->Scroller = NewObject(NULL,PROPGCLASS,
  134.                             GA_Top,            Screen->WBorTop + Screen->Font->ta_YSize + 2,
  135.                             GA_RelHeight,    -(Screen->WBorTop + Screen->Font->ta_YSize + 2 + SizeHeight + 1 + 2 * ArrowHeight),
  136.                             GA_Width,        SizeWidth - 8,
  137.                             GA_RelRight,    -(SizeWidth - 5),
  138.  
  139.                             PGA_Freedom,    FREEVERT,
  140.                             PGA_NewLook,    TRUE,
  141.                             PGA_Borderless,    TRUE,
  142.  
  143.                             PGA_Visible,    1,
  144.                             PGA_Total,        1,
  145.                         TAG_DONE))
  146.                         {
  147.                             if(ScrollerInfo->UpArrow = NewObject(NULL,BUTTONGCLASS,
  148.                                 GA_ID,            ARROW_UP,
  149.                                 GA_Image,        ScrollerInfo->UpImage,
  150.                                 GA_RelRight,    -(SizeWidth - 1),
  151.                                 GA_RelBottom,    -(SizeHeight - 1 + 2 * ArrowHeight),
  152.                                 GA_Height,        ArrowHeight,
  153.                                 GA_Width,        SizeWidth,
  154.                                 GA_Previous,    ScrollerInfo->Scroller,
  155.                                 GA_RightBorder,    TRUE,
  156.                             TAG_DONE))
  157.                             {
  158.                                 if(ScrollerInfo->DownArrow = NewObject(NULL,BUTTONGCLASS,
  159.                                     GA_ID,            ARROW_DOWN,
  160.                                     GA_Image,        ScrollerInfo->DownImage,
  161.                                     GA_RelRight,    -(SizeWidth - 1),
  162.                                     GA_RelBottom,    -(SizeHeight - 1 + ArrowHeight),
  163.                                     GA_Height,        ArrowHeight,
  164.                                     GA_Width,        SizeWidth,
  165.                                     GA_Previous,    ScrollerInfo->UpArrow,
  166.                                     GA_RightBorder,    TRUE,
  167.                                 TAG_DONE))
  168.                                 {
  169.                                     FreeScreenDrawInfo(Screen,DrawInfo);
  170.  
  171.                                     ScrollerInfo->MinWidth    = (Screen->WBorLeft) + (SizeWidth);
  172.                                     ScrollerInfo->MinHeight    = (Screen->WBorTop + Screen->Font->ta_YSize + 2) + (4) + (2*ArrowHeight) + (SizeHeight);
  173.  
  174.                                     return(ScrollerInfo);
  175.                                 }
  176.                             }
  177.                         }
  178.                     }
  179.                 }
  180.             }
  181.  
  182.             FreeScreenDrawInfo(Screen,DrawInfo);
  183.         }
  184.  
  185.         DeleteScroller(ScrollerInfo);
  186.     }
  187.  
  188.     return(NULL);
  189. }
  190.  
  191. STATIC LONG
  192. FindHitItem(struct GridData *GridData,UWORD MouseX,UWORD MouseY)
  193. {
  194.     LONG First,Last;
  195.     LONG x,y,i;
  196.  
  197.     First    = GridData->Top;
  198.     Last    = GridData->Top + GridData->Visible * GridData->MaxColumns;
  199.  
  200.     if(Last > GridData->ListSize)
  201.         Last = GridData->ListSize;
  202.  
  203.     for(y = 0, i = First ; i < Last && y < GridData->MaxLines ; y++)
  204.     {
  205.         for(x = 0 ; i < Last && x < GridData->MaxColumns ; x++, i++)
  206.         {
  207.             if(x * GridData->ItemWidth <= MouseX && MouseX < (x+1) * GridData->ItemWidth)
  208.             {
  209.                 if(y * GridData->ItemHeight <= MouseY && MouseY < (y+1) * GridData->ItemHeight)
  210.                     return(i);
  211.             }
  212.         }
  213.     }
  214.  
  215.     return(-1);
  216. }
  217.  
  218. STATIC VOID
  219. ResetGridData(struct GridData *GridData)
  220. {
  221.     memset(GridData,0,sizeof(struct GridData));
  222.  
  223.     GridData->LastSelected = -1;
  224.     GridData->UnselectThis = -1;
  225. }
  226.  
  227. STATIC VOID
  228. RecalculateSizes(struct GadgetInfo *GInfo,struct GridData *GridData)
  229. {
  230.     if(GridData->List)
  231.     {
  232.         struct RastPort LocalRastPort,*RPort;
  233.         LONG MaxWidth,Width,Count;
  234.         struct Node *Node;
  235.  
  236.         InitRastPort(RPort = &LocalRastPort);
  237.         SetFont(RPort,GInfo->gi_DrInfo->dri_Font);
  238.  
  239.         MaxWidth = 0;
  240.  
  241.         for(Node = GridData->List->lh_Head, Count = 0 ; Node->ln_Succ ; Node = Node->ln_Succ, Count++)
  242.         {
  243.             Width = TextLength(RPort,Node->ln_Name,strlen(Node->ln_Name));
  244.  
  245.             if(Width > MaxWidth)
  246.                 MaxWidth = Width;
  247.         }
  248.  
  249.         GridData->ItemWidth        = MARGIN_X + MaxWidth + MARGIN_X;
  250.         GridData->ItemHeight    = MARGIN_Y + RPort->TxHeight + MARGIN_Y;
  251.         GridData->ListSize        = Count;
  252.     }
  253.     else
  254.     {
  255.         GridData->ItemWidth        = 0;
  256.         GridData->ItemHeight    = 0;
  257.         GridData->ListSize        = 0;
  258.     }
  259. }
  260.  
  261. STATIC VOID
  262. RecalculateArea(struct IBox *Domain,struct Gadget *Gadget,struct GridData *GridData)
  263. {
  264.     LONG Width,Height;
  265.  
  266.     Width    = Domain->Width        + Gadget->Width;
  267.     Height    = Domain->Height    + Gadget->Height;
  268.  
  269.     GridData->LastWidth        = Domain->Width;
  270.     GridData->LastHeight    = Domain->Height;
  271.  
  272.     if(GridData->ListSize > 0 && GridData->ItemWidth > 0 && GridData->ItemHeight > 0)
  273.     {
  274.         GridData->MaxColumns    = Width / GridData->ItemWidth;
  275.         GridData->MaxLines        = Height / GridData->ItemHeight;
  276.  
  277.         if(GridData->MaxColumns > 0)
  278.         {
  279.             LONG Value;
  280.  
  281.             if((Value = (GridData->ListSize + GridData->MaxColumns - 1) / GridData->MaxColumns) < 1)
  282.                 Value = 1;
  283.  
  284.             GridData->Total = Value;
  285.  
  286.             if((Value = GridData->Top - (GridData->Top % GridData->MaxColumns)) < 0)
  287.                 Value = 0;
  288.  
  289.             GridData->Top = Value;
  290.  
  291.             if((Value = (GridData->ListSize - GridData->Top + GridData->MaxColumns - 1) / GridData->MaxColumns) < 1)
  292.                 Value = 1;
  293.  
  294.             if(Value > GridData->MaxLines)
  295.                 Value = GridData->MaxLines;
  296.  
  297.             GridData->Visible = Value;
  298.  
  299.             while(GridData->Top > 0 && GridData->Visible < GridData->MaxLines && GridData->Total > GridData->Visible)
  300.             {
  301.                 if(GridData->Top > GridData->MaxColumns)
  302.                     GridData->Top -= GridData->MaxColumns;
  303.                 else
  304.                     GridData->Top = 0;
  305.  
  306.                 if((Value = (GridData->ListSize - GridData->Top + GridData->MaxColumns - 1) / GridData->MaxColumns) < 1)
  307.                     Value = 1;
  308.  
  309.                 if(Value > GridData->MaxLines)
  310.                     Value = GridData->MaxLines;
  311.  
  312.                 GridData->Visible = Value;
  313.             }
  314.         }
  315.         else
  316.         {
  317.             GridData->Visible    = 1;
  318.             GridData->Total        = 1;
  319.         }
  320.     }
  321.     else
  322.     {
  323.         GridData->MaxColumns    = 0;
  324.         GridData->MaxLines        = 0;
  325.         GridData->Top            = 0;
  326.         GridData->Visible        = 1;
  327.         GridData->Total            = 1;
  328.     }
  329. }
  330.  
  331. STATIC VOID
  332. RenderItem(struct RastPort *RPort,UWORD *Pens,struct Node *Node,UWORD Left,UWORD Top,UWORD Width,UWORD Height,BOOL Selected)
  333. {
  334.     if(Node)
  335.     {
  336.         UWORD Shine,Shadow,Fill,TextPen,LabelWidth;
  337.         LONG Delta;
  338.  
  339.         if(Selected)
  340.         {
  341.             Shine    = Pens[SHADOWPEN];
  342.             Shadow    = Pens[SHINEPEN];
  343.             Fill    = Pens[FILLPEN];
  344.             TextPen    = Pens[FILLTEXTPEN];
  345.         }
  346.         else
  347.         {
  348.             Shine    = Pens[SHINEPEN];
  349.             Shadow    = Pens[SHADOWPEN];
  350.             Fill    = Pens[BACKGROUNDPEN];
  351.             TextPen    = Pens[TEXTPEN];
  352.         }
  353.  
  354.         LabelWidth = TextLength(RPort,Node->ln_Name,strlen(Node->ln_Name));
  355.  
  356.         SetABPenDrMd(RPort,Fill,Fill,JAM2);
  357.  
  358.         if(LabelWidth < Width - 2 * MARGIN_X)
  359.         {
  360.             LONG Rest;
  361.  
  362.             Delta = (Width - 2 * MARGIN_X - LabelWidth) / 2;
  363.  
  364.             if(Delta > 0)
  365.                 RectFill(RPort,Left + MARGIN_X,Top + MARGIN_Y,Left + MARGIN_X + Delta - 1,Top + Height - (MARGIN_Y + 1));
  366.  
  367.             Rest = Delta + LabelWidth;
  368.  
  369.             if(Rest < Width - 2 * MARGIN_X)
  370.                 RectFill(RPort,Left + MARGIN_X + Rest,Top + MARGIN_Y,Left + Width - (MARGIN_X + 1),Top + Height - (MARGIN_Y + 1));
  371.         }
  372.         else
  373.             Delta = 0;
  374.  
  375.         RectFill(RPort,Left + 1,                Top + 1,                Left + MARGIN_X - 1,            Top + Height - 2);
  376.         RectFill(RPort,Left + Width - MARGIN_X,    Top + 1,                Left + Width - 2,                Top + Height - 2);
  377.  
  378.         RectFill(RPort,Left + MARGIN_X,            Top + 1,                Left + Width - (MARGIN_X + 1),    Top + MARGIN_Y - 1);
  379.         RectFill(RPort,Left + MARGIN_X,            Top + Height - MARGIN_Y,Left + Width - (MARGIN_X + 1),    Top + Height - 2);
  380.  
  381.         SetAPen(RPort,TextPen);
  382.         Move(RPort,Left + MARGIN_X + Delta,Top + (Height - RPort->TxHeight) / 2 + RPort->TxBaseline);
  383.         Text(RPort,Node->ln_Name,strlen(Node->ln_Name));
  384.  
  385.         SetAPen(RPort,Shine);
  386.         RectFill(RPort,Left,Top,Left + Width - 1,Top);
  387.         RectFill(RPort,Left,Top + 1,Left,Top + Height - 1);
  388.  
  389.         SetAPen(RPort,Shadow);
  390.         RectFill(RPort,Left + Width - 1,Top + 1,Left + Width - 1,Top + Height - 1);
  391.         RectFill(RPort,Left + 1,Top + Height - 1,Left + Width - 2,Top + Height - 1);
  392.     }
  393.     else
  394.         EraseRect(RPort,Left,Top,Left + Width - 1,Top + Height - 1);
  395. }
  396.  
  397. STATIC struct Gadget *
  398. NewMethod(Class *class,struct Gadget *gadget,struct opSet *msg)
  399. {
  400.     struct Gadget *g;
  401.  
  402.     if(g = (struct Gadget *)DoSuperMethodA(class,(Object *)gadget,(Msg)msg))
  403.     {
  404.         ResetGridData(INST_DATA(class,g));
  405.  
  406.         CoerceMethod(class,(Object *)g,OM_SET,msg->ops_AttrList,msg->ops_GInfo);
  407.     }
  408.  
  409.     return(g);
  410. }
  411.  
  412. STATIC VOID
  413. NotifyGrid(Class *class,Object *object,struct GadgetInfo *GInfo,struct opUpdate *msg,struct GridData *GridData)
  414. {
  415.     struct TagItem Tags[4];
  416.     LONG Top,Total,Visible;
  417.  
  418.     if(!GridData->Visible || GridData->Total == GridData->Visible || GridData->MaxColumns < 1)
  419.     {
  420.         Top        = 0;
  421.         Total    = 1;
  422.         Visible    = 1;
  423.     }
  424.     else
  425.     {
  426.         Top        = GridData->Top / GridData->MaxColumns;
  427.         Total    = GridData->Total;
  428.         Visible    = GridData->Visible;
  429.     }
  430.  
  431.     Tags[0].ti_Tag        = GG_TopRow;
  432.         Tags[0].ti_Data    = Top;
  433.     Tags[1].ti_Tag        = GG_Total;
  434.         Tags[1].ti_Data    = Total;
  435.     Tags[2].ti_Tag        = GG_Visible;
  436.         Tags[2].ti_Data    = Visible;
  437.     Tags[3].ti_Tag        = TAG_DONE;
  438.  
  439.     DoSuperMethod(class,object,OM_NOTIFY,Tags,GInfo,((msg->MethodID == OM_UPDATE) ? (msg->opu_Flags) : 0L));
  440. }
  441.  
  442. STATIC VOID
  443. SetGrid(Class *class,struct Gadget *gadget,struct opSet *msg,...)
  444. {
  445.     va_list Args;
  446.  
  447.     va_start(Args,msg);
  448.     CoerceMethod(class,(Object *)gadget,OM_SET,Args,msg->ops_GInfo);
  449.     va_end(Args);
  450. }
  451.  
  452. STATIC ULONG
  453. SetMethod(Class *class,struct Gadget *gadget,struct opSet *msg)
  454. {
  455.     struct GridData *GridData = INST_DATA(class,gadget);
  456.     struct TagItem *List,*Item;
  457.     struct RastPort *RPort;
  458.     LONG Delta;
  459.  
  460.     List = msg->ops_AttrList;
  461.  
  462.     while(Item = NextTagItem(&List))
  463.     {
  464.         switch(Item->ti_Tag)
  465.         {
  466.             case GG_List:
  467.  
  468.                 if(msg->ops_GInfo != NULL)
  469.                     CoerceMethod(class,(Object *)gadget,GM_GOINACTIVE,msg->ops_GInfo,0);
  470.  
  471.                 ResetGridData(GridData);
  472.  
  473.                 GridData->List = (struct List *)Item->ti_Data;
  474.  
  475.                 break;
  476.  
  477.             case GG_Top:
  478.  
  479.                 if(msg->ops_GInfo != NULL && GridData->MaxColumns > 0)
  480.                 {
  481.                     LONG NewTop;
  482.  
  483.                     NewTop = (LONG)Item->ti_Data;
  484.  
  485.                     if(NewTop + (GridData->MaxLines - 1) * GridData->MaxColumns >= GridData->ListSize)
  486.                         NewTop = GridData->ListSize - (GridData->MaxLines - 1) * GridData->MaxColumns - 1;
  487.  
  488.                     if(NewTop < 0)
  489.                         NewTop = 0;
  490.  
  491.                     if(NewTop != GridData->Top)
  492.                     {
  493.                         UWORD HowTo;
  494.  
  495.                         HowTo = GREDRAW_REDRAW;
  496.  
  497.                         if(NewTop % GridData->MaxColumns == GridData->Top % GridData->MaxColumns)
  498.                         {
  499.                             LONG Delta;
  500.  
  501.                             Delta = (NewTop - GridData->Top) / GridData->MaxColumns;
  502.  
  503.                             CoerceMethod(class,(Object *)gadget,GM_GOINACTIVE,msg->ops_GInfo,0);
  504.  
  505.                             if(ABS(Delta) < GridData->MaxLines - 1)
  506.                             {
  507.                                 HowTo = GREDRAW_UPDATE;
  508.  
  509.                                 GridData->Direction = GridData->ItemHeight * Delta;
  510.  
  511.                                 if(Delta < 0)
  512.                                 {
  513.                                     GridData->From    = NewTop;
  514.                                     GridData->To    = NewTop + (-Delta) * GridData->MaxColumns - 1;
  515.                                 }
  516.                                 else
  517.                                 {
  518.                                     GridData->From    = NewTop + (GridData->MaxLines - Delta) * GridData->MaxColumns;
  519.                                     GridData->To    = NewTop + GridData->MaxLines * GridData->MaxColumns - 1;
  520.                                 }
  521.                             }
  522.                         }
  523.  
  524.                         GridData->Top = NewTop;
  525.  
  526.                         if(RPort = ObtainGIRPort(msg->ops_GInfo))
  527.                         {
  528.                             CoerceMethod(class,(Object *)gadget,GM_RENDER,msg->ops_GInfo,RPort,HowTo);
  529.  
  530.                             ReleaseGIRPort(RPort);
  531.                         }
  532.  
  533.                         GridData->Direction = 0;
  534.                     }
  535.                 }
  536.  
  537.                 break;
  538.  
  539.             case GG_TopRow:
  540.  
  541.                 SetGrid(class,gadget,msg,
  542.                     GG_Top,Item->ti_Data * GridData->MaxColumns,
  543.                 TAG_DONE);
  544.  
  545.                 break;
  546.  
  547.             case GG_ScrollArrow:
  548.  
  549.                 switch(Item->ti_Data)
  550.                 {
  551.                     case ARROW_UP:
  552.  
  553.                         Delta = -1;
  554.                         break;
  555.  
  556.                     case ARROW_DOWN:
  557.  
  558.                         Delta = 1;
  559.                         break;
  560.  
  561.                     default:
  562.  
  563.                         Delta = 0;
  564.                         break;
  565.                 }
  566.  
  567.                 if(Delta != 0)
  568.                 {
  569.                     SetGrid(class,gadget,msg,
  570.                         GG_Top,GridData->Top + Delta * GridData->MaxColumns,
  571.                     TAG_DONE);
  572.  
  573.                     NotifyGrid(class,(Object *)gadget,msg->ops_GInfo,(struct opUpdate *)msg,GridData);
  574.                 }
  575.  
  576.                 break;
  577.  
  578.             case GG_ResetNoRefresh:
  579.             case GG_Reset:
  580.  
  581.                 RecalculateSizes(msg->ops_GInfo,GridData);
  582.                 RecalculateArea(&msg->ops_GInfo->gi_Domain,gadget,GridData);
  583.  
  584.                 if(Item->ti_Tag == GG_Reset)
  585.                 {
  586.                     if(RPort = ObtainGIRPort(msg->ops_GInfo))
  587.                     {
  588.                         CoerceMethod(class,(Object *)gadget,GM_RENDER,msg->ops_GInfo,RPort,GREDRAW_REDRAW);
  589.  
  590.                         ReleaseGIRPort(RPort);
  591.                     }
  592.  
  593.                     NotifyGrid(class,(Object *)gadget,msg->ops_GInfo,(struct opUpdate *)msg,GridData);
  594.                 }
  595.  
  596.                 break;
  597.         }
  598.     }
  599.  
  600.     return(DoSuperMethodA(class,(Object *)gadget,(Msg)msg));
  601. }
  602.  
  603. STATIC ULONG
  604. GetMethod(Class *class,struct Gadget *gadget,struct opGet *msg)
  605. {
  606.     struct GridData *GridData = INST_DATA(class,gadget);
  607.  
  608.     switch(msg->opg_AttrID)
  609.     {
  610.         case GG_ItemWidth:
  611.  
  612.             *msg->opg_Storage = GridData->ItemWidth;
  613.             return(1);
  614.  
  615.         case GG_ItemHeight:
  616.  
  617.             *msg->opg_Storage = GridData->ItemHeight;
  618.             return(1);
  619.  
  620.         default:
  621.  
  622.             return(DoSuperMethodA(class,(Object *)gadget,(Msg)msg));
  623.     }
  624. }
  625.  
  626. STATIC ULONG
  627. RenderMethod(Class *class,struct Gadget *gadget,struct gpRender *msg)
  628. {
  629.     struct GridData *GridData = INST_DATA(class,gadget);
  630.  
  631.     if(GridData->List != NULL && GridData->ListSize == 0)
  632.     {
  633.         RecalculateSizes(msg->gpr_GInfo,GridData);
  634.         RecalculateArea(&msg->gpr_GInfo->gi_Domain,gadget,GridData);
  635.  
  636.         NotifyGrid(class,(Object *)gadget,msg->gpr_GInfo,(struct opUpdate *)msg,GridData);
  637.     }
  638.     else
  639.     {
  640.         if(msg->gpr_GInfo->gi_Domain.Width != GridData->LastWidth || msg->gpr_GInfo->gi_Domain.Height != GridData->LastHeight)
  641.             return(0);
  642.     }
  643.  
  644.     DB(kprintf("listsize = %ld\n",GridData->ListSize));
  645.  
  646.     if(GridData->ListSize == 0)
  647.         EraseRect(msg->gpr_RPort,gadget->LeftEdge,gadget->TopEdge,gadget->LeftEdge + gadget->Width - 1,gadget->TopEdge + gadget->Height - 1);
  648.     else
  649.     {
  650.         UWORD Left,Top,Width,Height;
  651.         struct RastPort *RPort;
  652.         struct Node *Node;
  653.         UWORD *Pens;
  654.         LONG i,x,y;
  655.  
  656.         RPort    = msg->gpr_RPort;
  657.         Pens    = msg->gpr_GInfo->gi_DrInfo->dri_Pens;
  658.  
  659.         Left    = gadget->LeftEdge;
  660.         Top        = gadget->TopEdge;
  661.         Width    = GridData->ItemWidth;
  662.         Height    = GridData->ItemHeight;
  663.  
  664.         for(i = 0, Node = GridData->List->lh_Head ; i < GridData->Top && Node->ln_Succ ; i++, Node = Node->ln_Succ);
  665.  
  666.         if(!Node->ln_Succ)
  667.             Node = NULL;
  668.  
  669.         DB(kprintf("maxlines %ld maxcolumns %ld node %08lx\n",GridData->MaxLines,GridData->MaxColumns,Node));
  670.  
  671.         if(msg->gpr_Redraw == GREDRAW_UPDATE)
  672.         {
  673.             if(GridData->Direction == 0)
  674.             {
  675.                 for(y = 0 ; y < GridData->MaxLines ; y++)
  676.                 {
  677.                     for(x = 0 ; x < GridData->MaxColumns ; x++)
  678.                     {
  679.                         if(i == GridData->LastSelected || i == GridData->UnselectThis)
  680.                             RenderItem(RPort,Pens,Node,Left + x * Width,Top + y * Height,Width,Height,(BOOL)(i == GridData->LastSelected));
  681.  
  682.                         if(Node)
  683.                         {
  684.                             if(Node->ln_Succ->ln_Succ)
  685.                                 Node = Node->ln_Succ;
  686.                             else
  687.                                 Node = NULL;
  688.                         }
  689.  
  690.                         i++;
  691.                     }
  692.                 }
  693.             }
  694.             else
  695.             {
  696.                 ScrollRasterBF(RPort,0,GridData->Direction,gadget->LeftEdge,gadget->TopEdge,gadget->LeftEdge + Width * GridData->MaxColumns - 1,gadget->TopEdge + Height * GridData->MaxLines - 1);
  697.  
  698.                 BeginUpdate(RPort->Layer);
  699.                 EndUpdate(RPort->Layer,TRUE);
  700.  
  701.                 for(y = 0 ; y < GridData->MaxLines ; y++)
  702.                 {
  703.                     for(x = 0 ; x < GridData->MaxColumns ; x++)
  704.                     {
  705.                         if(GridData->From <= i && i <= GridData->To)
  706.                             RenderItem(RPort,Pens,Node,Left + x * Width,Top + y * Height,Width,Height,(BOOL)(i == GridData->LastSelected));
  707.  
  708.                         if(Node)
  709.                         {
  710.                             if(Node->ln_Succ->ln_Succ)
  711.                                 Node = Node->ln_Succ;
  712.                             else
  713.                                 Node = NULL;
  714.                         }
  715.  
  716.                         i++;
  717.                     }
  718.                 }
  719.             }
  720.         }
  721.         else
  722.         {
  723.             if(GridData->LastSelected == -1)
  724.             {
  725.                 for(y = 0 ; y < GridData->MaxLines ; y++)
  726.                 {
  727.                     for(x = 0 ; x < GridData->MaxColumns ; x++)
  728.                     {
  729.                         RenderItem(RPort,Pens,Node,Left + x * Width,Top + y * Height,Width,Height,FALSE);
  730.  
  731.                         if(Node)
  732.                         {
  733.                             if(Node->ln_Succ->ln_Succ)
  734.                                 Node = Node->ln_Succ;
  735.                             else
  736.                                 Node = NULL;
  737.                         }
  738.                     }
  739.                 }
  740.             }
  741.             else
  742.             {
  743.                 for(y = 0 ; y < GridData->MaxLines ; y++)
  744.                 {
  745.                     for(x = 0 ; x < GridData->MaxColumns ; x++)
  746.                     {
  747.                         RenderItem(RPort,Pens,Node,Left + x * Width,Top + y * Height,Width,Height,(BOOL)(i == GridData->LastSelected));
  748.  
  749.                         if(Node)
  750.                         {
  751.                             if(Node->ln_Succ->ln_Succ)
  752.                                 Node = Node->ln_Succ;
  753.                             else
  754.                                 Node = NULL;
  755.                         }
  756.  
  757.                         i++;
  758.                     }
  759.                 }
  760.             }
  761.         }
  762.     }
  763.  
  764.     return(0);
  765. }
  766.  
  767. STATIC ULONG
  768. HitTestMethod(Class *class,struct Gadget *gadget,struct gpHitTest *msg)
  769. {
  770.     if(FindHitItem(INST_DATA(class,gadget),msg->gpht_Mouse.X,msg->gpht_Mouse.Y) != -1)
  771.         return(GMR_GADGETHIT);
  772.     else
  773.         return(0);
  774. }
  775.  
  776. STATIC ULONG
  777. GoActiveMethod(Class *class,struct Gadget *gadget,struct gpInput *msg)
  778. {
  779.     struct GridData *GridData = INST_DATA(class,gadget);
  780.     LONG Selected;
  781.  
  782.     Selected = FindHitItem(GridData,msg->gpi_Mouse.X,msg->gpi_Mouse.Y);
  783.  
  784.     if(Selected == -1)
  785.         return(GMR_NOREUSE);
  786.     else
  787.     {
  788.         struct RastPort *RPort;
  789.  
  790.         GridData->UnselectThis = -1;
  791.         GridData->LastSelected = Selected;
  792.  
  793.         if(RPort = ObtainGIRPort(msg->gpi_GInfo))
  794.         {
  795.             CoerceMethod(class,(Object *)gadget,GM_RENDER,msg->gpi_GInfo,RPort,GREDRAW_UPDATE);
  796.  
  797.             ReleaseGIRPort(RPort);
  798.         }
  799.  
  800.         return(GMR_MEACTIVE);
  801.     }
  802. }
  803.  
  804. STATIC ULONG
  805. GoInactiveMethod(Class *class,struct Gadget *gadget,struct gpGoInactive *msg)
  806. {
  807.     struct GridData *GridData = INST_DATA(class,gadget);
  808.  
  809.     if(GridData->LastSelected != -1)
  810.     {
  811.         struct RastPort *RPort;
  812.  
  813.         GridData->UnselectThis = GridData->LastSelected;
  814.         GridData->LastSelected = -1;
  815.  
  816.         if(RPort = ObtainGIRPort(msg->gpgi_GInfo))
  817.         {
  818.             CoerceMethod(class,(Object *)gadget,GM_RENDER,msg->gpgi_GInfo,RPort,GREDRAW_UPDATE);
  819.  
  820.             ReleaseGIRPort(RPort);
  821.         }
  822.  
  823.         GridData->UnselectThis = -1;
  824.     }
  825.  
  826.     return(0);
  827. }
  828.  
  829. STATIC ULONG
  830. HandleInputMethod(Class *class,struct Gadget *gadget,struct gpInput *msg)
  831. {
  832.     struct GridData *GridData;
  833.     LONG Selected;
  834.  
  835.     if(msg->gpi_IEvent->ie_Code == MENUDOWN)
  836.     {
  837.         CoerceMethod(class,(Object *)gadget,GM_GOINACTIVE,msg->gpi_GInfo,0);
  838.  
  839.         return(GMR_NOREUSE);
  840.     }
  841.  
  842.     GridData = INST_DATA(class,gadget);
  843.  
  844.     if(msg->gpi_IEvent->ie_Code == SELECTUP)
  845.     {
  846.         ULONG Result;
  847.  
  848.         if(GridData->LastSelected == -1)
  849.             Result = GMR_NOREUSE;
  850.         else
  851.         {
  852.             Result = GMR_NOREUSE | GMR_VERIFY;
  853.  
  854.             *msg->gpi_Termination = GridData->LastSelected;
  855.         }
  856.  
  857.         CoerceMethod(class,(Object *)gadget,GM_GOINACTIVE,msg->gpi_GInfo,0);
  858.  
  859.         return(Result);
  860.     }
  861.  
  862.     if(msg->gpi_IEvent->ie_Class == IECLASS_TIMER)
  863.     {
  864.         if(msg->gpi_Mouse.Y < 0)
  865.         {
  866.             SetGadgetAttrs(gadget,msg->gpi_GInfo->gi_Window,msg->gpi_GInfo->gi_Requester,
  867.                 GG_Top,GridData->Top - GridData->MaxColumns,
  868.             TAG_DONE);
  869.  
  870.             NotifyGrid(class,(Object *)gadget,msg->gpi_GInfo,(struct opUpdate *)msg,GridData);
  871.         }
  872.         else
  873.         {
  874.             if(msg->gpi_Mouse.Y >= GridData->Visible * GridData->ItemHeight)
  875.             {
  876.                 SetGadgetAttrs(gadget,msg->gpi_GInfo->gi_Window,msg->gpi_GInfo->gi_Requester,
  877.                     GG_Top,GridData->Top + GridData->MaxColumns,
  878.                 TAG_DONE);
  879.  
  880.                 NotifyGrid(class,(Object *)gadget,msg->gpi_GInfo,(struct opUpdate *)msg,GridData);
  881.             }
  882.         }
  883.     }
  884.  
  885.     Selected = FindHitItem(GridData,msg->gpi_Mouse.X,msg->gpi_Mouse.Y);
  886.  
  887.     if(Selected != GridData->LastSelected)
  888.     {
  889.         struct RastPort *RPort;
  890.  
  891.         GridData->UnselectThis = GridData->LastSelected;
  892.         GridData->LastSelected = Selected;
  893.  
  894.         if(RPort = ObtainGIRPort(msg->gpi_GInfo))
  895.         {
  896.             CoerceMethod(class,(Object *)gadget,GM_RENDER,msg->gpi_GInfo,RPort,GREDRAW_UPDATE);
  897.  
  898.             ReleaseGIRPort(RPort);
  899.         }
  900.  
  901.         GridData->UnselectThis = -1;
  902.     }
  903.  
  904.     return(GMR_MEACTIVE);
  905. }
  906.  
  907. STATIC ULONG ASM SAVE_DS
  908. ClassDispatcher(REG(a0) Class *class,REG(a2) struct Gadget *gadget,REG(a1) Msg msg)
  909. {
  910.     switch(msg->MethodID)
  911.     {
  912.         case OM_GET:
  913.  
  914.             return(GetMethod(class,gadget,(struct opGet *)msg));
  915.  
  916.         case OM_NEW:
  917.  
  918.             return((ULONG)NewMethod(class,gadget,(struct opSet *)msg));
  919.  
  920.         case OM_SET:
  921.         case OM_UPDATE:
  922.  
  923.             return(SetMethod(class,gadget,(struct opSet *)msg));
  924.  
  925.         case GM_RENDER:
  926.  
  927.             return(RenderMethod(class,gadget,(struct gpRender *)msg));
  928.  
  929.         case GM_HITTEST:
  930.  
  931.             return(HitTestMethod(class,gadget,(struct gpHitTest *)msg));
  932.  
  933.         case GM_GOACTIVE:
  934.  
  935.             return(GoActiveMethod(class,gadget,(struct gpInput *)msg));
  936.  
  937.         case GM_GOINACTIVE:
  938.  
  939.             return(GoInactiveMethod(class,gadget,(struct gpGoInactive *)msg));
  940.  
  941.         case GM_HANDLEINPUT:
  942.  
  943.             return(HandleInputMethod(class,gadget,(struct gpInput *)msg));
  944.  
  945.         default:
  946.  
  947.             return(DoSuperMethodA(class,(Object *)gadget,msg));
  948.     }
  949. }
  950.  
  951. STATIC BOOL
  952. ChangeWindowSize(struct Window *LocalWindow,LONG MinWidth,LONG MinHeight)
  953. {
  954.     ULONG IntuiLock;
  955.     LONG Left,Top,Width,Height;
  956.     BOOL NeedChange;
  957.  
  958.     NeedChange = FALSE;
  959.  
  960.     IntuiLock = LockIBase(NULL);
  961.  
  962.     if(MinWidth > LocalWindow->Width)
  963.     {
  964.         Width = MinWidth;
  965.         NeedChange = TRUE;
  966.     }
  967.     else
  968.         Width = LocalWindow->Width;
  969.  
  970.     if(MinHeight > LocalWindow->Height)
  971.     {
  972.         Height = MinHeight;
  973.         NeedChange = TRUE;
  974.     }
  975.     else
  976.         Height = LocalWindow->Height;
  977.  
  978.     if(LocalWindow->LeftEdge + Width > LocalWindow->WScreen->Width)
  979.     {
  980.         Left = LocalWindow->WScreen->Width - Width;
  981.         NeedChange = TRUE;
  982.     }
  983.     else
  984.         Left = LocalWindow->LeftEdge;
  985.  
  986.     if(LocalWindow->TopEdge + Height > LocalWindow->WScreen->Height)
  987.     {
  988.         Top = LocalWindow->WScreen->Height - Height;
  989.         NeedChange = TRUE;
  990.     }
  991.     else
  992.         Top = LocalWindow->TopEdge;
  993.  
  994.     UnlockIBase(IntuiLock);
  995.  
  996.     if(NeedChange)
  997.     {
  998.         struct IntuiMessage *Message;
  999.         BOOL Done;
  1000.         LONG i;
  1001.  
  1002.         ChangeWindowBox(LocalWindow,Left,Top,Width,Height);
  1003.  
  1004.         for(i = 0 ; i < 5*60 ; i++)
  1005.         {
  1006.             Done = FALSE;
  1007.  
  1008.             while(Message = (struct IntuiMessage *)GetMsg(LocalWindow->UserPort))
  1009.             {
  1010.                 if(Message->Class == IDCMP_CHANGEWINDOW)
  1011.                     Done = TRUE;
  1012.  
  1013.                 ReplyMsg((struct Message *)Message);
  1014.             }
  1015.  
  1016.             if(Done)
  1017.                 break;
  1018.             else
  1019.                 WaitTOF();
  1020.         }
  1021.     }
  1022.  
  1023.     return(NeedChange);
  1024. }
  1025.  
  1026. STATIC BOOL
  1027. WindowSizeControl(struct Window *LocalWindow,Object *LocalObject)
  1028. {
  1029.     ULONG ItemWidth,ItemHeight;
  1030.     BOOL DidReset;
  1031.  
  1032.     GetAttr(GG_ItemWidth,    LocalObject,&ItemWidth);
  1033.     GetAttr(GG_ItemHeight,    LocalObject,&ItemHeight);
  1034.  
  1035.     ItemWidth    += LocalWindow->BorderLeft    + LocalWindow->BorderRight;
  1036.     ItemHeight    += LocalWindow->BorderTop    + LocalWindow->BorderBottom;
  1037.  
  1038.     if(ItemWidth < GridScroller->MinWidth)
  1039.         ItemWidth = GridScroller->MinWidth;
  1040.  
  1041.     if(ItemHeight < GridScroller->MinHeight)
  1042.         ItemHeight = GridScroller->MinHeight;
  1043.  
  1044.     if(ChangeWindowSize(LocalWindow,ItemWidth,ItemHeight))
  1045.     {
  1046.         SetGadgetAttrs((struct Gadget *)LocalObject,LocalWindow,NULL,
  1047.             GG_Reset,TRUE,
  1048.         TAG_DONE);
  1049.  
  1050.         DidReset = TRUE;
  1051.     }
  1052.     else
  1053.         DidReset = FALSE;
  1054.  
  1055.     WindowLimits(LocalWindow,ItemWidth,ItemHeight,LocalWindow->WScreen->Width,LocalWindow->WScreen->Height);
  1056.  
  1057.     return(DidReset);
  1058. }
  1059.  
  1060.     /* RefreshFastWindow():
  1061.      *
  1062.      *    Refresh the contents of the fast! macro window.
  1063.      */
  1064.  
  1065. VOID
  1066. RefreshFastWindow()
  1067. {
  1068.     if(FastWindow)
  1069.     {
  1070.         SetGadgetAttrs((struct Gadget *)GridObject,FastWindow,NULL,
  1071.             GG_ResetNoRefresh,TRUE,
  1072.         TAG_DONE);
  1073.  
  1074.         EraseWindow(FastWindow,NULL);
  1075.  
  1076.         if(!WindowSizeControl(FastWindow,GridObject))
  1077.         {
  1078.             SetGadgetAttrs((struct Gadget *)GridObject,FastWindow,NULL,
  1079.                 GG_Reset,TRUE,
  1080.             TAG_DONE);
  1081.         }
  1082.     }
  1083. }
  1084.  
  1085.     /* CloseFastWindow():
  1086.      *
  1087.      *    Close the fast! macro window and free the associated resources.
  1088.      */
  1089.  
  1090. VOID
  1091. CloseFastWindow()
  1092. {
  1093.     CheckItem(MEN_FAST_MACROS_WINDOW,FALSE);
  1094.  
  1095.     if(FastWindow)
  1096.     {
  1097.         PutWindowInfo(WINDOW_FAST,FastWindow->LeftEdge,FastWindow->TopEdge,FastWindow->Width,FastWindow->Height);
  1098.  
  1099.         ClearMenuStrip(FastWindow);
  1100.         CloseWindowSafely(FastWindow);
  1101.  
  1102.         FastWindow = NULL;
  1103.     }
  1104.  
  1105.     if(GridObject)
  1106.     {
  1107.         DisposeObject(GridObject);
  1108.         GridObject = NULL;
  1109.     }
  1110.  
  1111.     if(GridScroller)
  1112.     {
  1113.         DeleteScroller(GridScroller);
  1114.         GridScroller = NULL;
  1115.     }
  1116.  
  1117.     if(GridClass)
  1118.     {
  1119.         FreeClass(GridClass);
  1120.         GridClass = NULL;
  1121.     }
  1122. }
  1123.  
  1124.     /* OpenFastWindow():
  1125.      *
  1126.      *    Open the fast! macro window.
  1127.      */
  1128.  
  1129. BOOL
  1130. OpenFastWindow()
  1131. {
  1132.     if(FastWindow)
  1133.     {
  1134.         ActivateWindow(FastWindow);
  1135.         return(TRUE);
  1136.     }
  1137.  
  1138.     if(GridClass = MakeClass(NULL,GADGETCLASS,NULL,sizeof(struct GridData),NULL))
  1139.     {
  1140.         InitHook(&GridClass->cl_Dispatcher,(HOOKFUNC)ClassDispatcher,NULL);
  1141.  
  1142.         if(GridScroller = CreateScroller(Window->WScreen))
  1143.         {
  1144.             STATIC struct TagItem GridToPropMap[] =
  1145.             {
  1146.                 GG_TopRow,    PGA_Top,
  1147.                 GG_Visible,    PGA_Visible,
  1148.                 GG_Total,    PGA_Total,
  1149.  
  1150.                 TAG_DONE
  1151.             };
  1152.  
  1153.             if(GridObject = NewObject(GridClass,NULL,
  1154.                 GA_RelVerify,    TRUE,
  1155.                 GG_List,        &FastMacroList,
  1156.                 ICA_TARGET,        GridScroller->Scroller,
  1157.                 ICA_MAP,        GridToPropMap,
  1158.             TAG_DONE))
  1159.             {
  1160.                 STATIC struct TagItem PropToGridMap[] =
  1161.                 {
  1162.                     PGA_Top,    GG_TopRow,
  1163.  
  1164.                     TAG_DONE
  1165.                 };
  1166.  
  1167.                 STATIC struct TagItem ArrowToGridMap[] =
  1168.                 {
  1169.                     GA_ID,        GG_ScrollArrow,
  1170.  
  1171.                     TAG_DONE
  1172.                 };
  1173.  
  1174.                 LONG Left,Top,Width,Height;
  1175.  
  1176.                 Left    = 0;
  1177.                 Top        = 0;
  1178.                 Width    = 0;
  1179.                 Height    = 0;
  1180.  
  1181.                 GetWindowInfo(WINDOW_FAST,&Left,&Top,&Width,&Height,100,100);
  1182.  
  1183.                 SetAttrs(GridScroller->Scroller,
  1184.                     ICA_TARGET,        GridObject,
  1185.                     ICA_MAP,        PropToGridMap,
  1186.                 TAG_DONE);
  1187.  
  1188.                 SetAttrs(GridScroller->UpArrow,
  1189.                     ICA_TARGET,        GridObject,
  1190.                     ICA_MAP,        ArrowToGridMap,
  1191.                 TAG_DONE);
  1192.  
  1193.                 SetAttrs(GridScroller->DownArrow,
  1194.                     ICA_TARGET,        GridObject,
  1195.                     ICA_MAP,        ArrowToGridMap,
  1196.                 TAG_DONE);
  1197.  
  1198.                 if(FastWindow = OpenWindowTags(NULL,
  1199.                     WA_Left,            Left,
  1200.                     WA_Top,                Top,
  1201.                     WA_Width,            Width,
  1202.                     WA_Height,            Height,
  1203.                     WA_DepthGadget,        TRUE,
  1204.                     WA_SimpleRefresh,    TRUE,
  1205.                     WA_CloseGadget,        TRUE,
  1206.                     WA_DragBar,            TRUE,
  1207.                     WA_Title,            LocaleString(MSG_FASTMACROS_FAST_MACROS_TXT),
  1208.                     WA_SizeGadget,        TRUE,
  1209.                     WA_SizeBRight,        TRUE,
  1210.                     WA_Gadgets,            GridScroller->Scroller,
  1211.                     WA_NewLookMenus,    TRUE,
  1212.                     WA_Activate,        TRUE,
  1213.                     BackfillTag,        &BackfillHook,
  1214.                     OpenWindowTag,        Window->WScreen,
  1215.  
  1216.                     AmigaGlyph ? WA_AmigaKey  : TAG_IGNORE, AmigaGlyph,
  1217.                     CheckGlyph ? WA_Checkmark : TAG_IGNORE, CheckGlyph,
  1218.                 TAG_DONE))
  1219.                 {
  1220.                     FastWindow->UserPort = Window->UserPort;
  1221.  
  1222.                     if(ModifyIDCMP(FastWindow,DEFAULT_IDCMP | IDCMP_CLOSEWINDOW | IDCMP_GADGETUP | IDCMP_NEWSIZE | IDCMP_CHANGEWINDOW))
  1223.                     {
  1224.                         WindowLimits(FastWindow,FastWindow->Width,FastWindow->Height,FastWindow->WScreen->Width,FastWindow->WScreen->Height);
  1225.  
  1226.                         SetAttrs(GridObject,
  1227.                             GA_Left,        FastWindow->BorderLeft,
  1228.                             GA_Top,            FastWindow->BorderTop,
  1229.                             GA_RelWidth,    -(FastWindow->BorderLeft    + FastWindow->BorderRight),
  1230.                             GA_RelHeight,    -(FastWindow->BorderTop        + FastWindow->BorderBottom),
  1231.                         TAG_DONE);
  1232.  
  1233.                         AddGList(FastWindow,(struct Gadget *)GridObject,(UWORD)-1,1,NULL);
  1234.                         RefreshGList((struct Gadget *)GridObject,FastWindow,NULL,1);
  1235.  
  1236.                         WindowSizeControl(FastWindow,GridObject);
  1237.  
  1238.                         SetMenuStrip(FastWindow,Menu);
  1239.  
  1240.                         CheckItem(MEN_FAST_MACROS_WINDOW,TRUE);
  1241.  
  1242.                         return(TRUE);
  1243.                     }
  1244.                     else
  1245.                     {
  1246.                         FastWindow->UserPort = NULL;
  1247.  
  1248.                         CloseWindow(FastWindow);
  1249.  
  1250.                         FastWindow = NULL;
  1251.                     }
  1252.                 }
  1253.             }
  1254.         }
  1255.     }
  1256.  
  1257.     CloseFastWindow();
  1258.  
  1259.     return(FALSE);
  1260. }
  1261.  
  1262.     /* HandleFastWindowGadget(ULONG MsgClass,UWORD MsgCode):
  1263.      *
  1264.      *    Process fast! macro window input.
  1265.      */
  1266.  
  1267. VOID
  1268. HandleFastWindowGadget(ULONG MsgClass,UWORD MsgCode)
  1269. {
  1270.     struct MacroNode *Node;
  1271.  
  1272.     switch(MsgClass)
  1273.     {
  1274.         case IDCMP_GADGETUP:
  1275.  
  1276.             if(Node = (struct MacroNode *)GetListNode(MsgCode,&FastMacroList))
  1277.             {
  1278.                 if(Node->Code[0])
  1279.                     SerialCommand(Node->Code);
  1280.             }
  1281.  
  1282.             break;
  1283.  
  1284.         case IDCMP_NEWSIZE:
  1285.  
  1286.             SetGadgetAttrs((struct Gadget *)GridObject,FastWindow,NULL,
  1287.                 GG_Reset,TRUE,
  1288.             TAG_DONE);
  1289.  
  1290.             break;
  1291.     }
  1292. }
  1293.